package com.doeis.minaserver.session;

import io.netty.channel.ChannelHandlerContext;

import java.net.InetSocketAddress;

import org.apache.log4j.Logger;

import com.doeis.minaserver.listener.ConnectionCloseListener;
import com.doeis.minaserver.nio.NioServiceEventLoop;
import com.doeis.minaserver.packet.Packet;


/**
 * c2s的链接信息
 * @author nortan
 *
 */
public class ClientConnection implements NioConnection {
	
	/**
	 * 通讯链接情况
	 */
	public static final byte STATUS_CLOSED = -1;
    public static final byte STATUS_CONNECTED = 1;
    public static final byte STATUS_LOGIN = 2;
    
    
    private NioServiceEventLoop nioServiceEventLoop; 
    
	private byte status;
    private String userid;//登陆者
    private String switchboard_id; //总帐号和 数据库dbname
    private String registrationID;//唯一标识符
    
	private ChannelHandlerContext channelHandlerContext ;
	
	private ConnectionCloseListener closeListener;	
	private static final Logger log = Logger.getLogger(ClientConnection.class);
    
	public ClientConnection(ChannelHandlerContext channelHandlerContext, NioServiceEventLoop nioServiceEventLoop){
		this.nioServiceEventLoop = nioServiceEventLoop;
		this.channelHandlerContext = channelHandlerContext;
		this.status = STATUS_CONNECTED;
	}
	
    /**
     * 取得当前的链接状态
     * @return
     */
    public byte getStatus(){
    	return status;
    }
    
    /**
     * 设置当前链接状态
     * @param status
     */
    public void setStatus(byte status){
    	this.status = status;
    }
    
	public String getRegistrationID() {
		return registrationID;
	}

	public void setRegistrationID(String registrationID) {
		this.registrationID = registrationID;
	}

	public String getUserid() {
		return userid;
	}

	public void setUserid(String userid) {
		this.userid = userid;
	}
	public String getSwitchboard_id() {
		return switchboard_id;
	}
	public void setSwitchboard_id(String switchboard_id) {
		this.switchboard_id = switchboard_id;
	}

	/**
     * 取得当前session对应的主机
     * @return
     */
    public String getHostAddress(){
    	InetSocketAddress address =  (InetSocketAddress)channelHandlerContext.channel().remoteAddress();
    	return address.getAddress().getHostAddress();
    }

	public String getHostName(){
    	InetSocketAddress address =  (InetSocketAddress)channelHandlerContext.channel().remoteAddress();
    	return address.getHostName();
    }

    /**
     * 关闭当前链接
     */
	public void close() {
		boolean closedSuccessfully = false;
        synchronized (this) {
            if (!isClosed()) {                
            	channelHandlerContext.close();
                status = STATUS_CLOSED;
                closedSuccessfully = true;
            }
        }
        if (closedSuccessfully) {
            notifyCloseListeners();
        }
	}
	
	public boolean isClosed() {
		return STATUS_CLOSED == status ;
	}

	/**
	 * 发送数据包，注意发送错误或者离线时数据包的处理，目前还没有处理
	 */
	public void deliver(Packet packet) {
		if( !isClosed() ){
			try {
				channelHandlerContext.writeAndFlush(packet);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}


	public void registerCloseListener(ConnectionCloseListener listener) {
		if (closeListener != null) {
            throw new IllegalStateException("Close listener already configured");
        }
        if (isClosed()) {
            listener.onConnectionClose(channelHandlerContext);
        }
        else {
            closeListener = listener;
        }
	}

	public void removeCloseListener(ConnectionCloseListener listener) {
		if (closeListener == listener) {
            closeListener = null;
        }
	}
	
	private void notifyCloseListeners() {
        if (closeListener != null) {
            try {
                closeListener.onConnectionClose(channelHandlerContext);
            } catch (Exception e) {
            	log.error("Error notifying listener: " + closeListener, e);
            }
        }
    }
	
	
	public NioServiceEventLoop getNioServiceEventLoop() {
		return nioServiceEventLoop;
	}


	public ChannelHandlerContext getChannelHandlerContext() {
		return channelHandlerContext;
	}

	@Override
	public String toString() {
		return "ClientConnection [nioServiceEventLoop=" + nioServiceEventLoop
				+ ", status=" + status + ", userid=" + userid
				+ ", channelHandlerContext=" + channelHandlerContext
				+ ", closeListener=" + closeListener + "]";
	}

	
	

}
